<template>
    <div>
        <section>
            <div class="title">文本内容</div>
            <div style="border: 1px solid #ccc">
                <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" />
                <Editor
                    style="height: 600px; overflow-y: hidden"
                    v-model="logData.context"
                    :defaultConfig="editorConfig"
                    @onCreated="handleCreated"
                />
            </div>
        </section>
        <section>
            <div class="title">上传附件</div>
            <my-upload drag :on-success="uploadFileSuccess" multiple>
                <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                <div class="el-upload__text">
                    将文件拖到此处或者
                    <em>点击此处文字上传</em>
                </div>
                <template #tip>
                    <div class="el-upload__tip">建议上传压缩包</div>
                </template>
            </my-upload>
        </section>
        <section>
            <div class="title">已上传附件资源列表</div>
            <el-table :data="showList" style="width: 100%" border>
                <el-table-column label="资源id" prop="id"></el-table-column>
                <el-table-column label="文件名" prop="name"></el-table-column>
                <el-table-column label="上传时间" prop="uploadTime">
                    <template #default="{ row }">
                        {{ row && new Date(row.uploadTime).toLocaleString() }}
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #default="{ $index }">
                        <el-button type="danger" @click="removeStatic($index)">删除文件</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </section>
        <section>
            <el-button type="primary" @click="uploadLog">上传日志</el-button>
        </section>
    </div>
</template>

<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { onBeforeUnmount, ref, shallowRef, computed } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import type { LogUploadForm } from "@/api/log/type";
import { ElMessage } from "element-plus";
// 引入仓库
import useUserStore from "@/store/modules/user";
import useSubjectStore from "@/store/modules/subject";
// 引入接口
import { reqUploadLog, reqLogDetail } from "@/api/log";
import { reqRemoveUseless, reqDeleteFile } from "@/api/file";
const userStore = useUserStore();
const subjectStore = useSubjectStore();
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();
const handleCreated = (editor: any) => {
    editorRef.value = editor; // 记录 editor 实例，重要！
};
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
    // 每次退出前都要清理图片
    deleteUseless();
});
// 工具栏的配置
const toolbarConfig = {
    mode: "default",
    excludeKeys: ["group-video"], //不需要上传视频的选项
};
// 记录上传过的图片的列表
let imageList: Set<string> = new Set();
const editorConfig = {
    placeholder: "请输入内容...",
    mode: "default", // 配置上传图片的地址
    MENU_CONF: {
        uploadImage: {
            server: "/api/need/file/insertImg",
            // 自定义增加 http  header
            headers: {
                token: userStore.token,
            },
            fieldName: "image",
            maxFileSize: 20 * 1024 * 1024, //设置最大图片大小为20M
        },
        insertImage: {
            onInsertedImage(imageNode: any) {
                if (imageNode == null) return;
                const { src } = imageNode;
                // 获取文件路径的末尾
                const fileName = src.substring(src.lastIndexOf("/") + 1);
                // 添加路径到set中
                imageList.add(fileName);
            },
        },
    },
};
// 接收参数
const props = defineProps(["id", "name"]);
// 定义表单内容
const logData = ref<LogUploadForm>({
    id: props.id === -1 ? "" : props.id, // 表示修改日志的时候
    subject_id: "",
    staticIds: [],
    context: "",
    preText: "",
});
// 定义静态资源列表
// eslint-disable-next-line no-undef
const resourceList = ref<Resource[]>([]);

// 获取日志详情内容
const getLogDetail = async () => {
    // 请求数据
    const res = await reqLogDetail(props.id);
    if (res.code === 200 && typeof res.data === "object") {
        // 赋值内容
        logData.value.context = res.data.context;
        resourceList.value = res.data.resource;
    } else {
        ElMessage.error(res.data as string);
    }
};
// 如果props不为-1则应该获取日志内容进行修改
const init = async () => {
    if (props.id === -1) {
        return;
    }
    await getLogDetail();
    const editor = editorRef.value;

    // 获取完内容之后，要初始化图片列表
    const res = editor.getElemsByType("image").map((item: any) => {
        return item.src.substring(item.src.lastIndexOf("/") + 1);
    });
    imageList = new Set(res);
};
init();
// 文件上传成功的钩子
// eslint-disable-next-line no-undef
const uploadFileSuccess = (res: Resource | string) => {
    if (typeof res === "string") {
        return;
    }
    resourceList.value.push(res);
    return;
};

// 上传日志
const uploadLog = async () => {
    // 判空操作
    if (isEmpty()) {
        return;
    }
    const editor = editorRef.value;
    // 清理多余的图片
    await deleteUseless();
    // 清理多余的文件
    await deleteFile();
    // 获取到编辑器的内容
    let preText = editor.getText();
    if (preText.length > 200) {
        preText = preText.substring(0, 200) + "...";
    }
    logData.value.preText = preText;
    // 赋值subject_id
    logData.value.subject_id = subjectStore.currentId;
    // 赋值staticIds
    // eslint-disable-next-line no-undef
    logData.value.staticIds = resourceList.value.map((item: Resource) => item.id);
    // 上传日志
    const res = await reqUploadLog(logData.value);
    if (res.code === 200) {
        ElMessage.success("上传成功");
        // 成功后回到首页
        subjectStore.backSubjectHome();
        // 同时删除页面
        subjectStore.removePage(props.name);
    } else {
        ElMessage.error(res.data);
    }
};

// 删除附件
const removeList = ref<Array<{ id: number; name: string }>>([]);
const removeStatic = (index: number) => {
    const resource = resourceList.value[index];
    removeList.value.push({
        id: resource.id,
        name: resource.save_path,
    });
    resourceList.value.splice(index, 1);
    return;
};

// 资源展示列表
const showList = computed(() => {
    return resourceList.value.filter((resource) => {
        const flag = removeList.value.some((removeItem) => {
            return removeItem.id === resource.id;
        });
        return !flag;
    });
});
// 清理相册图片
const deleteUseless = async () => {
    const editor = editorRef.value;
    // 获取当前编辑器中的图片列表，并且只取其路径中的文件名
    const hasUploadList = editor.getElemsByType("image").map((item: any) => {
        return item.src.substring(item.src.lastIndexOf("/") + 1);
    });
    // imageList包含了上传过的所有的图片，去除所有存在于hashUploadList中的图片即为不需要的图片
    // 整理出多余的参数
    hasUploadList.forEach((item: string) => {
        imageList.delete(item);
    });
    // 发起删除图片的请求
    await reqRemoveUseless({
        nameList: Array.from(imageList),
    });
    return;
};

// 清理不需要的附件
const deleteFile = async () => {
    if (removeList.value.length === 0) {
        return;
    }
    const res = await reqDeleteFile({
        fileList: removeList.value,
    });
    if (res.code === 200) {
        return;
    } else {
        ElMessage.error(res.data);
    }
    return;
};

// 判空
const isEmpty = () => {
    if (editorRef.value.getText().trim() === "" && resourceList.value.length === 0) {
        ElMessage.error("日志内容不能为空");
        return true;
    }
    return false;
};
</script>

<style lang="scss" scoped>
section {
    margin-top: 20px;
}

// 模拟descriptions中header的样式
.title {
    font-size: 16px;
    font-weight: 700;
    color: var(--el-text-color-primary);
    margin-bottom: 20px;
}
</style>
